package com.mindcraft.user.serivce.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mindcraft.base.utils.CommonConst;
import com.mindcraft.base.utils.MindCraftEnum;
import com.mindcraft.user.Dto.AuthParamsDto;
import com.mindcraft.user.Dto.McUserExt;
import com.mindcraft.user.mapper.McUserMapper;
import com.mindcraft.user.po.McUser;
import com.mindcraft.user.serivce.AuthService;
import com.mindcraft.user.serivce.WxAuthService;
import com.mindcraft.user.vo.WXUserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Mr.M
 * @version 1.0
 * @description 微信扫码认证
 * @date 2022/9/29 12:12
 */
@Slf4j
@Service("wx_authservice")
public class WxAuthServiceImpl implements AuthService, WxAuthService {

    @Autowired
    McUserMapper mcUserMapper;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    WxAuthServiceImpl currentProxy;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${weixin.appid}")
    String appid;
    @Value("${weixin.secret}")
    String secret;

    @Override
    public McUserExt execute(AuthParamsDto authParamsDto) {

        //账号
        String username = authParamsDto.getUsername();
        McUser user = mcUserMapper.selectOne(new LambdaQueryWrapper<McUser>().eq(McUser::getUsername, username));
        if (user == null) {
            //返回空表示用户不存在
            throw new RuntimeException("账号不存在");
        }
        McUserExt xcUserExt = new McUserExt();
        BeanUtils.copyProperties(user, xcUserExt);
        return xcUserExt;
    }

    @Override
    public WXUserVO wxAuth(String code) {

        //收到code调用微信接口申请access_token
        Map<String, String> access_token_map = getAccess_token(code);
        if (access_token_map == null) {
            return null;
        }
        System.out.println(access_token_map);
        String openid = access_token_map.get("openid");
        String access_token = access_token_map.get("access_token");
        //拿access_token查询用户信息
        Map<String, String> userinfo = getUserinfo(access_token, openid);
        if (userinfo == null) {
            return null;
        }

        //添加用户到数据库
        WXUserVO wxUserVO = currentProxy.addWxUser(userinfo);

        return wxUserVO;
    }


    @Transactional
    public WXUserVO addWxUser(Map userInfo_map) {

        WXUserVO wxUserVO = new WXUserVO();

        String unionid = userInfo_map.get("unionid").toString();
        String userToken = "";

        //根据unionid查询数据库
        McUser mcUser = mcUserMapper.selectOne(new LambdaQueryWrapper<McUser>().eq(McUser::getWxUnionid, unionid));
        String userId = mcUser.getId();
        if (redisTemplate.hasKey(CommonConst.USER_TOKEN + mcUser.getId())) {
            userToken = (String) redisTemplate.opsForValue().get(CommonConst.USER_TOKEN + mcUser.getId());
        }else{
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            userToken = CommonConst.USER_ACCESS_TOKEN + uuid;

            redisTemplate.opsForValue().set(userToken, mcUser, CommonConst.TOKEN_EXPIRE, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(CommonConst.USER_TOKEN + mcUser.getId(), userToken, CommonConst.TOKEN_EXPIRE,TimeUnit.SECONDS);
        }

        wxUserVO.setAccessToken(userToken);

        String randomuserId = UUID.randomUUID().toString();
        mcUser = new McUser();
        mcUser.setId(randomuserId);
        mcUser.setWxUnionid(unionid);
        //记录从微信得到的昵称
        mcUser.setNickname(userInfo_map.get("nickname").toString());
        mcUser.setUserpic(userInfo_map.get("headimgurl").toString());
        mcUser.setName(userInfo_map.get("nickname").toString());
        mcUser.setUsername(userInfo_map.get("nickname").toString());
        mcUser.setPassword(unionid);
        mcUser.setUtype("101001");//学生类型
        mcUser.setStatus("1");//用户状态
        mcUser.setCreateTime(LocalDateTime.now());
        BeanUtils.copyProperties(mcUser,wxUserVO);

        //插入微信用户数据
        if (mcUser == null) {
            mcUserMapper.insert(mcUser);
        }else{
            wxUserVO.setId(userId);
        }

        return wxUserVO;
    }

    private Map<String, String> getAccess_token(String code) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, appid, secret, code);

        log.info("调用微信接口申请access_token, url:{}", wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        String result = exchange.getBody();
        log.info("调用微信接口申请access_token: 返回值:{}", result);
        Map<String, String> resultMap = JSON.parseObject(result, Map.class);

        return resultMap;
    }


    private Map<String, String> getUserinfo(String access_token, String openid) {

        String wxUrl_template = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
        //请求微信地址
        String wxUrl = String.format(wxUrl_template, access_token, openid);

        log.info("调用微信接口申请access_token, url:{}", wxUrl);

        ResponseEntity<String> exchange = restTemplate.exchange(wxUrl, HttpMethod.POST, null, String.class);

        //防止乱码进行转码
        String result = new String(exchange.getBody().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        log.info("调用微信接口申请access_token: 返回值:{}", result);
        Map<String, String> resultMap = JSON.parseObject(result, Map.class);

        return resultMap;
    }


//    private int qqLoginCheck() {
//
//        String qrsig = qrsign();
//        String url = "https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&ptqrtoken="
//                + GetqrToekn(qrsig) + "&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-" + System.currentTimeMillis() / 1000
//                + "&js_ver=23111510&js_type=1&login_sig=wq86AwJQI8EHy*64BTWWA2G85ljJlI8BQvGND1nHFN-mcXYlKbHL2yPVGoDiEXmR&pt_uistyle=40&aid=549000912&daid=5&";
//
//        try {
//
//            Thread.sleep(500); // 休眠500毫秒
//            HttpClient client = HttpClientBuilder.create().build();
//            HttpGet request = new HttpGet(url);
//            request.setHeader("Cookie", "qrsig=" + qrsig);
//
//            CloseableHttpResponse response = null;
//            String responseText = "";
//            String responseBody = null;
//            try {
//                response = (CloseableHttpResponse) client.execute(request);
//                HttpEntity entity = response.getEntity();
//
//                if (entity != null) {
//                    try (InputStream inputStream = entity.getContent()) {
//                        // 从输入流中读取内容
//                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//                        StringBuilder stringBuilder = new StringBuilder();
//                        String line;
//                        while ((line = reader.readLine()) != null) {
//                            stringBuilder.append(line);
//                        }
//                        responseBody = stringBuilder.toString();
//                    } catch (IOException e) {
//                        // 处理异常
//                    }
//                }
//                System.out.println(responseBody);
//            } catch (IOException e) {
//                throw new RuntimeException(e);
//            }
//
//            if (response.getStatusLine().getStatusCode() == 200) {
//                responseText = responseBody;
//
//                if (responseText.contains("二维码未失效")) {
//                    System.out.println(LocalDateTime.now().toString() + " 二维码未失效");
//                } else if (responseText.contains("二维码认证中")) {
//                    System.out.println(LocalDateTime.now().toString() + " 二维码认证中");
//                } else if (responseText.contains("二维码已失效")) {
//                    System.out.println(LocalDateTime.now().toString() + " 二维码已失效");
//                    qrsig = qrsign(); // 获取新的qrsig
//                    String ptqrtoken = String.valueOf(GetqrToekn(qrsig)); // 获取新的ptqrtoken
//                } else {
//                    //TODO 获取用户信息
//                    System.out.println(LocalDateTime.now().toString() + " 登录成功");
//                    Map<String,String> qqNumberorName = getQQNumberOrName(responseText);
//
////                    return qqNumber;
//                }
//            } else {
//                System.out.println(LocalDateTime.now().toString() + " 请求登录失败");
//            }
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        return 1;
//
//    }
//
//    private Map<String, String> getQQNumberOrName(String responseText) {
//        Map<String ,String> map = new HashMap<>();
//        Pattern pattern = Pattern.compile("uin=(\\d+)");
//        Matcher matcher = pattern.matcher(responseText);
//        if (matcher.find()) {
//            String uin = matcher.group(1);
//            map.put("qqacount",uin);
//            System.out.println("uin: " + uin);
//        }
//        int start = responseText.indexOf("'登录成功！', '") + "'登录成功！', '".length();
//        int end = responseText.indexOf("'", start);
//        String qqname = responseText.substring(start, end);
//        map.put("qqname",qqname);
//        System.out.println(qqname);
//        return map;
//    }
//
//
//
//    private String qrsign() {
//
//        String url = "https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=3&d=72&v=4&t=0.4440979972998541&daid=5&pt_3rd_aid=0";
//        String qrsig = "";
//        int qrsignRequestCount = 1;
//        try (CloseableHttpClient client = HttpClients.createDefault()) {
//            HttpGet request = new HttpGet(url);
//            HttpResponse response = client.execute(request);
//
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//
//                for (org.apache.http.Header header : response.getHeaders("Set-Cookie")) {
//                    String[] cookieParts = header.getValue().split(";");
//                    for (String part : cookieParts) {
//                        if (part.startsWith("qrsig=")) {
//                            qrsig = part.substring(6);
//                            break;
//                        }
//                    }
//                }
//
//                HttpEntity entity = response.getEntity();
//                byte[] content = EntityUtils.toByteArray(entity);
//                Path filePath = Paths.get("QQToolChest.png");
//                if (Files.exists(filePath)) {
//                    Files.delete(filePath);
//                }
//                Files.write(filePath, content, StandardOpenOption.CREATE);
//
//                System.out.println(java.time.LocalTime.now().toString() + " 登录二维码获取成功");
//            } else {
//                System.out.println(java.time.LocalTime.now().toString() + " 获取二维码失败");
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        if(redisTemplate.hasKey("qrsignRequestCount")){
//            qrsignRequestCount = (int) redisTemplate.opsForValue().get("qrsignRequestCount");
//        }else{
//            redisTemplate.opsForValue().set("qrsignRequestCount",1,1000, TimeUnit.SECONDS);
//        }
//        if(redisTemplate.hasKey("qrsig")){
//            qrsig = (String) redisTemplate.opsForValue().get("qrsig");
//        }else{
//            redisTemplate.opsForValue().set("qrsig",qrsig,1000, TimeUnit.SECONDS);
//        }
//
//
//
//        if (String.valueOf(qrsignRequestCount) == null || qrsignRequestCount>5){
//            redisTemplate.opsForValue().set("qrsignRequestCount",1,1000, TimeUnit.SECONDS);
//            redisTemplate.opsForValue().set("qrsig",qrsig,1000, TimeUnit.SECONDS);
//            return qrsig;
//        }else{
//            //获取老qrsig
//            qrsig = (String) redisTemplate.opsForValue().get("qrsig");
//            redisTemplate.opsForValue().set("qrsignRequestCount",qrsignRequestCount+1,1000, TimeUnit.SECONDS);
//            return qrsig;
//        }
////        return qrsig;
//    }


    private static int GetqrToekn(String qrsig) {
        int n = qrsig.length();
        int i = 0;
        int e = 0;
        while (n > i) {
            e += (e << 5) + (int) qrsig.charAt(i);
            i += 1;
        }
        return 2147483647 & e;
    }

}